<?php


namespace app\api\controller;


use app\common\exception\ApiException;
use app\common\model\UploadFiles as UploadFilesModel;
use OSS\Core\OssException;
use think\facade\Filesystem;
use think\facade\Request;

class Image extends Base
{
    /**
     * 图片文件上传
     * @return \think\response\Json
     * @throws OssException
     */
    public function upload()
    {
        $folder_name = $this->request->param('file/s','file');
        if(empty($folder_name)) return json(getJson('文件不存在',0,[]));
        $result = UploadFilesModel::upload($folder_name);
        $result['file'] = get_host().$result['file'];
        return json($result);
//        return json(getJson('文件上传成功',1,$result));
    }

    // ajax 请求 文件上传
    function File(){
        $file = Request::file('file');
        //文件校验
        $fileSize = 1024 * 1024 * 1024 * 10; // 10M   ,fileExt:gif,jpg,png
        $result=validate(['file' => ['fileSize:'.$fileSize]])->check(['file' => $file]);
        if($result){
            //上传到服务器
            $path = Filesystem::disk('public')->putFile('uploadFiles',$file);
            //获取图片路径
            //获取绝对路径
            $picCover = comple_host($path);
            //原始文件名
            $fileName = $file->getOriginalName();
            $data = ['picCover'=>$picCover,'fileName'=>$fileName];
            $this->success('上传成功','',$data);
        }
    }



    public function demo(){
        return view();
    }

    /**
     * base64上传 图片上传
     */
    public function upload3(){
        $base64 = $this->request->param('file');
        $res = $this->saveBase64Image($base64);
        if($res['code']==0){
            success($res['msg'],$res['url']);
        }else{
            error($res['msg']);
        }
    }


    private function saveBase64Image($base64_image_content){

        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
            //图片后缀
            $type = $result[2];
            //保存位置--图片名
            $image_name=date('His').str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT).".".$type;
            $image_file_path = '/uploads/image/'.date('Ymd');
            $image_file = ROOT_PATH.'public'.$image_file_path;
            $imge_real_url = $image_file.'/'.$image_name;
            $imge_web_url = $image_file_path.'/'.$image_name;
            if (!file_exists($image_file)){
                mkdirs($image_file, 0777);
            }
            //解码
            $decode=base64_decode(str_replace($result[1], '', $base64_image_content));
            if (file_put_contents($imge_real_url, $decode)){
                $data['code']=0;
                $data['imageName']=$image_name;
                $data['url']=get_host().$imge_web_url;
                $data['msg']='保存成功！';
            }else{
                $data['code']=1;
                $data['imgageName']='';
                $data['url']='';
                $data['msg']='图片保存失败！';
            }
        }else{
            $data['code']=1;
            $data['imgageName']='';
            $data['url']='';
            $data['msg']='base64图片格式有误！';
        }
        return $data;
    }

    /**
     * 接收二进制文件上传
     */
    public function upload2(){
        $data = file_get_contents("php://input");
//        dump($data);exit;
        $fileType = '';
        $this->getFileType($data, $fileType);
        if ($fileType == 'unknown'){
            error('文件类型识别失败');
        }

        //拼接文件后缀：生成唯一文件名
        $uniqueName = uniqid('app_', true) . $fileType;

        $saveDb = $this->uploadBinaryFile($data, $uniqueName);

        exit("文件存放路径为 [ {$saveDb} ]");
    }

    /**
     * 接收文件上传
     */
    public function upload4(){
        $folder_name = $this->request->param('file/s','file');
        if(empty($folder_name)) return json(getJson('文件不存在',0,[]));


    }

    /**
     * ****** 这个方法自己测试一下，我不能保证是对的，因为我也是百度的 >_< ******
     * 根据二进制流获取文件类型
     * @param $file 文件数据
     * @param $fileType 文件后缀
     */
    function getFileType($file, &$fileType)
    {
        /* 参考：PHP通过二进制流判断文件类型 https://blog.csdn.net/xwlljn/article/details/85134958 */
        // 文件头标识 (2 bytes)
        $bin = substr($file,0, 2);
        $strInfo = unpack("C2chars", $bin);
        $typeCode = intval($strInfo['chars1'] . $strInfo['chars2']);

        /* 参考：利用文件头判断文件类型 https://blog.csdn.net/weixin_34267123/article/details/85506211 */
        // 文件头对应的文件后缀关联数组
        $fileToSuffix = [
            255216 => '.jpg',
            7173 => '.gif',
            6677 => '.bmp',
            13780 => '.png',
            208207 => '.xls',   //注意：doc 文件会识别成 208207
            8075 => '.zip',     //注意：xlsx文件会识别成 8075
            239187 => '.js',
            6787 => '.swf',
            7067 => '.txt',
            7368 => '.mp3',
            4838 => '.wma',
            7784 => '.mid',
            8297 => '.rar',
            6063 => '.xml',
        ];

        $fileType = empty($fileToSuffix[$typeCode]) ? 'unknown' : $fileToSuffix[$typeCode];
    }

    /**
     * 上传二进制文件并保存
     * @param $data 文件内容
     * @param $uniqueName 唯一文件名
     * @param string $path 自定义文件保存目录
     * @return string
     */
    public function uploadBinaryFile($data, $uniqueName, $path = '/file/app/')
    {
        $thinkPath = Env::get('root_path');    //框架应用根目录，命名空间为：use think\facade\Env;
        $thinkPath = str_replace('\\', '/', $thinkPath);   //把 \\ 替换成 /

        $relativePath = 'public' . $path . date('Y-m-d') . '/';   //文件存放的相对路径（相对应用根目录）
        $saveDb = $relativePath . $uniqueName;  //存放到数据表的路径
        $savePath = $thinkPath . $saveDb;       //文件存放的绝对路径

        $mkdirPath = $thinkPath . $relativePath;
        if (!is_dir($mkdirPath)) {    //文件夹不存在，则创建；并给最大权限 777
            mkdir($mkdirPath,0777,true);
            chmod($mkdirPath,0777);
        }

        file_put_contents($savePath, $data);    //保存文件

        return $saveDb;
    }
}